//
// Created by chaseaishang on 23-4-15.
// Camera  Now It's just OrthographicCamera
//

#pragma once
#include "Render/StdAfx.h"
#include "Event.h"
#include "MouseEvent.h"
#include "KeyEvent.h"
#include "ApplicationEvent.h"
#include "Input.h"
enum Camera_Movement
{
    FORWARD,
    BACKWARD,
    LEFT,
    RIGHT
};
//PerspectiveCamera
class PerspectiveCamera
{
public:
    PerspectiveCamera(float fov,float aspectRatio, float zNear, float zFar);
    void init(glm::vec3 position ,
              glm::vec3 up , float yaw ,
              float pitch ,float zoom);
    void SetProjection(float fov,float aspectRatio, float zNear, float zFar);

    void SetDirection(Camera_Movement direction, float velocity);

    void GetEulerAngle(float &yaw,float &pitch)const{yaw=m_Yaw;pitch=m_Pitch;}
    void SetEulerAngle(float yaw,float pitch){m_Yaw=yaw;m_Pitch=pitch;RecalculateViewMatrix();};
    const glm::vec3& GetPosition() const { return m_Position; }
    void SetPosition(const glm::vec3& position) { m_Position = position; RecalculateViewMatrix(); }

    const glm::mat4& GetProjectionMatrix() const { return m_ProjectionMatrix; }
    const glm::mat4& GetViewMatrix() const { return m_ViewMatrix; }
    const glm::mat4& GetViewProjectionMatrix() const { return m_ViewProjectionMatrix; }
private:
    void RecalculateViewMatrix();
private:

    glm::mat4 m_ProjectionMatrix;
    glm::mat4 m_ViewMatrix;
    glm::mat4 m_ViewProjectionMatrix;

    glm::vec3 m_Position = { 0.0f, 0.0f, 0.0f };
    glm::vec3 m_Front{ 0.0f, 0.0f, 0.0f };
    glm::vec3 m_Up{ 0.0f, 0.0f, 0.0f };
    glm::vec3 m_Right{ 0.0f, 0.0f, 0.0f };
    glm::vec3 m_WorldUp{ 0.0f, 0.0f, 0.0f };
    float m_aspectRatio;
    float m_Yaw;
    float m_Pitch;
    float m_ZoomLevel;
};
class OrthographicCamera
{
public:
    OrthographicCamera(float left, float right, float bottom, float top, float zNear, float zFar);
    void init(glm::vec3 position ,
              glm::vec3 up , float yaw ,
              float pitch );
    void SetProjection(float left, float right, float bottom, float top, float zNear, float zFar);

    void SetDirection(Camera_Movement direction, float velocity);
    void SetEulerAngle(float yaw,float pitch){m_Yaw=yaw;m_Pitch=pitch;RecalculateViewMatrix();};
    const glm::vec3& GetPosition() const { return m_Position; }
    void SetPosition(const glm::vec3& position) { m_Position = position; RecalculateViewMatrix(); }

    const glm::mat4& GetProjectionMatrix() const { return m_ProjectionMatrix; }
    const glm::mat4& GetViewMatrix() const { return m_ViewMatrix; }
    const glm::mat4& GetViewProjectionMatrix() const { return m_ViewProjectionMatrix; }
private:
    void RecalculateViewMatrix();
private:

    glm::mat4 m_ProjectionMatrix;
    glm::mat4 m_ViewMatrix;
    glm::mat4 m_ViewProjectionMatrix;

    glm::vec3 m_Position = { 0.0f, 0.0f, 0.0f };
    glm::vec3 m_Front{ 0.0f, 0.0f, 0.0f };
    glm::vec3 m_Up{ 0.0f, 0.0f, 0.0f };
    glm::vec3 m_Right{ 0.0f, 0.0f, 0.0f };
    glm::vec3 m_WorldUp{ 0.0f, 0.0f, 0.0f };

    float m_Yaw;
    float m_Pitch;
    float m_ZoomLevel;
};
class OrthographicCameraController
{
public:
    OrthographicCameraController(
            float left,float right,float bottom,float top,float znear,float zfar,
            float aspectRatio, bool rotation = false);
//glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f) 左、右、下、上
    void OnUpdate(float ts);
    void OnEvent(Event& e);

    OrthographicCamera& GetCamera() { return m_Camera; }
    const OrthographicCamera& GetCamera() const { return m_Camera; }

    float GetZoomLevel() const { return m_ZoomLevel; }
    void SetZoomLevel(float level) { m_ZoomLevel = level; }
private:
    bool OnMouseScrolled(MouseScrolledEvent& e);
    bool OnWindowResized(WindowResizeEvent& e);
private:
    float m_AspectRatio;
    float m_ZoomLevel = 1.0f;
    float m_MovementSpeed;
    float m_MouseSensitivity;
    OrthographicCamera m_Camera;



    glm::vec3 m_CameraPosition = { 0.0f, 0.0f, 0.0f };
    float m_CameraRotation = 0.0f; //In degrees, in the anti-clockwise direction
    float m_CameraTranslationSpeed = 5.0f, m_CameraRotationSpeed = 180.0f;
};
class PerspectiveCameraController
{
public:
    PerspectiveCameraController(float fov,float aspectRatio,float zNear,float zFar);

    void OnUpdate(float ts);
    void OnEvent(Event& e);

    PerspectiveCamera& GetCamera() { return m_Camera; }
    const PerspectiveCamera& GetCamera() const { return m_Camera; }

    float GetZoomLevel() const { return m_ZoomLevel; }
    void SetZoomLevel(float level) { m_ZoomLevel = level; }

    //m_MovementSpeed
private:

    bool OnMouseScrolled(MouseScrolledEvent& e);
    bool OnWindowResized(WindowResizeEvent& e);
    bool OnKeyPressed(KeyPressedEvent&e);
    bool OnMouseButtonPressed(MouseButtonPressedEvent&e);
    bool OnMouseButtonReleased(MouseButtonReleasedEvent&e);
    bool OnMouseMoved(MouseMovedEvent&e);
private:
    Mouse m_mouse;
    float m_AspectRatio;
    float m_ZoomLevel = 1.0f;
    float m_MovementSpeed;
public:
    float getMMovementSpeed() const;

    void setMMovementSpeed(float mMovementSpeed);

private:
    float m_MouseSensitivity;
    PerspectiveCamera m_Camera;
    bool m_rotate_on{false};
    bool m_first_Mouse{true};
    std::pair<float,float>m_MousePosition;





};
